home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 426-450 / disk_437 / patchcompiler / source / patchstarcompiler.ass < prev    next >
Text File  |  1992-05-06  |  24KB  |  1,161 lines

  1.     opt    l+
  2.  
  3.     XREF    PATCH_MODULE_END,PATCH_MODULE_START
  4.     XREF.l    PATCH_MODULE_SIZE
  5.  
  6. ; V19
  7. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  8. ; ­­                    PatchStartCompiler                          ­­
  9. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  10. ; ­­ © 1990 Roger Fischlin, Steigerwaldweg 6, 6450 Hanau 7, Germany ­­
  11. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  12.  
  13.  
  14.     incdir       "ram:include/"
  15.  
  16.             include     exec/memory.i
  17.     include    exec/exec_lib.i
  18.     include    exec/interrupts.i
  19.     include    libraries/dos_lib.i
  20.     include    libraries/dos.i
  21.     include    libraries/dosextens.i
  22.  
  23.  
  24.  
  25. DOS    macro            ; one library, one macro .....
  26.     move.l    a5,a6
  27.     jsr    _LVO\1(a6)
  28.     endm
  29.  
  30.  
  31.  
  32. DOS_TEXT    macro
  33.     lea.l    .Text\@(pc),a0
  34.     moveq.l    #.TextEnd\@-.Text\@,d0
  35.     bsr    CLI_Text
  36.     bra.s    .Label\@
  37. .Text\@    dc.b    \1
  38. .TextEnd\@
  39.     even
  40. .Label\@    tst    d0
  41.     endm
  42.  
  43. PSC_ERROR    macro
  44.     lea.l    .Text\@(pc),a0
  45.     moveq.l    #.TextEnd\@-.Text\@,d0
  46.     bsr    CLI_Text
  47.     bra.s    .Label\@
  48. .Text\@    dc.b    "    ERROR : "
  49.     dc.b    \1
  50.     dc.b    10
  51. .TextEnd\@
  52.     even
  53. .Label\@    tst    d0
  54.     endm
  55.  
  56.     clr.b    -1(a0,d0)
  57.     move.l    a0,CommandString
  58.     lea    dosname(pc),a1        ; open DOS
  59.     moveq.l    #33,d0
  60.     CALLEXEC     OpenLibrary
  61.     move.l    d0,a5
  62.     tst.l    d0
  63.     beq    NoDOS
  64.     bsr    Main
  65.     move.l    a5,a1        ; close DOS
  66.     CALLEXEC    CloseLibrary
  67. NoDOS    moveq.l    #0,d0
  68.     rts
  69. dosname    DOSNAME
  70. CommandString    dc.l    0
  71. Source_FH    dc.l    0
  72. Object_FH    dc.l    0
  73. Info_FH    dc.l    0
  74. LineCounter    dc.l    0
  75. BEGINCounter    dc.l    0
  76. LastIF    dc.b    0
  77. InfoName    dc.l    0
  78. SourceName    dc.l    0
  79. PatchName    dc.l    0
  80.     even
  81.  
  82.  
  83.  
  84. Main    bsr    COMMAND        ; check args 
  85.     tst.w    d0
  86.     bmi    INFO
  87.  
  88.     DOS_TEXT    <10,$9b,"4m"," PatchStar - Compiler V1.00  © 1990 by Roger Fischlin ",$9b,"0m",10,10>
  89.     bne    .Error
  90.  
  91.     move.l    PatchName(pc),d1        ; open object file
  92.     move.l    #MODE_NEWFILE,d2
  93.     DOS    Open
  94.     move.l    d0,Object_FH
  95.     bne.s    .Label2
  96.     DOS_TEXT    <"couldn't open object file !",10>
  97.     bra    .Error
  98.  
  99. .Label2    DOS_TEXT    <$9b,"1;32m"," 1.Writing patch module",10,$9b,"0;31m">
  100.     bsr    WRITE_MODULE
  101.     move.w    d0,d6
  102.     DOS_TEXT    <" done.",10,10>
  103.     tst.w    d6        ; error ?
  104.     bne    DeleteObject
  105.  
  106.  
  107.     DOS_TEXT    <$9b,"1;32m"," 2.Writing info string",10,$9b,"0;31m">
  108.     bsr    WRITE_INFO
  109.     move.w    d0,d6
  110.     DOS_TEXT    <" done.",10,10>
  111.     tst.w    d6        ; error ?
  112.     bne    DeleteObject
  113.  
  114.  
  115.     DOS_TEXT    <$9b,"1;32m"," 3.Compiling",10,$9b,"0;31m">
  116.     bsr    COMPILE_SOURCE
  117.     move.w    d0,d6
  118.     DOS_TEXT    <10," done.",10,10>
  119.     tst.w    d6        ; error ?
  120.     bne.s    DeleteObject
  121.  
  122.     DOS_TEXT    <$9b,"1;32m"," 4.Saving as executable",10,$9b,"0;31m">
  123.     bsr    EXECUTABLE
  124.     move.w    d0,d6
  125.     DOS_TEXT    <" done.",10,10>
  126.     tst.w    d6        ; error ?
  127.     bne.s    DeleteObject
  128.  
  129.  
  130.  
  131.     move.l    Object_FH(pc),d1    ; close object file
  132.     DOS    Close
  133. .Error    rts
  134.  
  135.  
  136.  
  137. DeleteObject    move.l    Object_FH(pc),d1    ; close object file
  138.     DOS    Close
  139.     move.l    PatchName(pc),d1    ; delete object
  140.     DOS    DeleteFile
  141.     DOS_TEXT    <10,10>
  142.     rts
  143.  
  144. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  145. ; ­­                   COMPILE SOURCE                     ­­
  146. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  147.  
  148. COMPILE_SOURCE    move.l    SourceName(pc),d1    ; open source file
  149.     move.l    #MODE_OLDFILE,d2
  150.     DOS    Open
  151.     move.l    d0,Source_FH
  152.     bne.s    .Label1
  153.     PSC_ERROR    <"couldn't open source file !",10>
  154.     bra    NoSource
  155.  
  156. .Label1    clr.l    LineCounter
  157.     clr.b    LastIF
  158. NextLine    moveq.l    #0,d0        ; check if CTRL-C 
  159.     moveq.l    #0,d1
  160.     CALLEXEC    SetSignal
  161.     btst    #12,d0
  162.     beq.s    .NoUserBreak
  163.     DOS_TEXT    <" User break .",10>    ; write msg
  164.     bra    COMP_Error
  165.  
  166. .NoUserBreak    addq.l    #1,LineCounter
  167.     bsr    WriteLine        ; write current line number
  168.     bsr    ReadLine        ; get next line
  169.     tst.b    Line        ; end of file ?
  170.     beq    COMP_CloseSource
  171.     tst    d0
  172.     beq    .NoError        ; error ?
  173.     bmi    .DosError
  174.     PSC_ERROR    <"Line too long !">
  175.     bra    COMP_Error
  176. .DosError    PSC_ERROR    <"DOS error !">
  177.     bra    COMP_Error
  178.  
  179. .NoError    lea.l    Line(pc),a0
  180.     bsr    NextCommand        ; skip spaces etc.
  181.     tst    d0
  182.     beq    NextLine        ; no more commands...
  183.  
  184.     move.b    (a0)+,d0        ; a0 ^command
  185.     bsr    UpCase        ; upcase
  186.     cmp.b    #"B",d0        ; which command ?
  187.     beq    BEGIN
  188.     tst.b    LastIF        ; if the last command is IF, the next one must be BEGIN !
  189.     beq.s    .NotIF
  190.     PSC_ERROR    <"IF without BEGIN !">    ; write error msg
  191.     bra    DeleteObject
  192.  
  193. .NotIF    cmp.b    #"E",d0
  194.     beq    END
  195.     cmp.b    #"Q",d0
  196.     beq    QUIT
  197.     cmp.b    #"T",d0
  198.     beq    TEXT
  199.     cmp.b    #"P",d0
  200.     beq    PATCH
  201.     cmp.b    #"C",d0
  202.     beq    CHECK
  203.     cmp.b    #"I",d0
  204.     beq    _IF
  205.     subq.l    #1,a0
  206.     bra    PATCH_2        ; patch ? without "PATCH"
  207.  
  208. SytaxError    PSC_ERROR    <"sytax error !">
  209.     bra    COMP_Error
  210.  
  211. DOSError    PSC_ERROR    <"DOS error !">
  212.     bra.s    COMP_Error
  213.  
  214.  
  215. COMP_CloseSource
  216.     tst.l    BEGINCounter        ; check if there are more BEGINs without ENDs
  217.     beq.s    .OK
  218.     PSC_ERROR    <"BEGIN without END !",10>
  219.     bra.s    COMP_Error
  220.  
  221. .OK    move.l    Object_FH(pc),d1    ; write END OF PATCH
  222.     move.l    #EOP,d2
  223.     moveq.l    #2,d3
  224.     DOS    Write
  225.     cmp.l    d0,d3
  226.     bne    DOSError
  227.     move.l    Source_FH(pc),d1
  228.     DOS    Close
  229.     moveq.l    #0,d0        ; no error
  230.     rts
  231. COMP_Error    move.l    Source_FH(pc),d1
  232.     DOS    Close
  233. NoSource    moveq.l    #-1,d0        ; error
  234.     rts
  235.  
  236. EOP    dc.b    ".",0
  237.     even
  238.  
  239. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  240. ; ­­                Write info string                     ­­
  241. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  242.  
  243. INFO    lea.l    .String(pc),a0
  244.     move.l    #.StringEnd-.String,d0
  245.     bra    CLI_Text
  246.  
  247. .String    dc.b    10,10," ",$9b,"4;31;42m"
  248.     dc.b    "                    PatchStar - Compiler V1.00                    "
  249.     dc.b    $9b,"0;31;40m",10,10
  250.     dc.b    "                     This program is ",$9b,"1m","FREEWARE",$9b,"0m"," !",10
  251.     dc.b    " © 1990"
  252.     dc.b    $9b,"0;33m"
  253.     dc.b    "  Roger Fischlin, Steigerwaldweg 6, D-6450 Hanau 7, Germany",10
  254.     dc.b    $9b,"0;31m",10
  255.     dc.b    "      Usage : PSCompiler <info file> <source file> <patch>",10,10
  256. .StringEnd    
  257.     even
  258.  
  259.  
  260. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  261. ; ­­                Write Text to CLI                     ­­
  262. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  263.  
  264. CLI_Text    movem.l    a0/d0,-(sp)
  265.     DOS    Output        ; get handle to CLI window
  266.     move.l    d0,d1
  267.     move.l    (sp)+,d3
  268.     move.l    (sp)+,d2
  269.     DOS    Write
  270.     cmp.l    d0,d3        ; write error
  271.     beq.s    .OK
  272.     moveq.l    #-1,d0
  273.     rts
  274. .OK    moveq.l    #0,d0
  275.     rts
  276.  
  277. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  278. ; ­­                       WriteLine                      ­­
  279. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  280.  
  281. WriteLine    lea.l    .Number(pc),a0
  282.     move.l    LineCounter(pc),d0
  283.     bsr    .MakeASCII
  284.     move.l    a0,d0
  285.     lea.l    .LineText(pc),a0
  286.     sub.l    a0,d0
  287.     bra    CLI_Text
  288.  
  289.  
  290. .MakeASCII    moveq.l    #10-1,d2
  291.     moveq.l    #0,d3
  292.     lea.l    .Potenzen(pc),a1
  293. .Label1    move.b    #"0"-1,d1
  294. .Label2    addq    #1,d1
  295.     sub.l    (a1),d0
  296.     bcc.s    .Label2
  297.     add.l    (a1)+,d0
  298.     tst.b    d2
  299.     beq.s    .Label3
  300.     cmp.b    #"0",d1
  301.     beq.s    .Label4
  302.     moveq.l    #1,d3
  303.     bra.s    .Label3
  304. .Label4    tst.b    d3
  305.     beq.s    .Label5
  306. .Label3    move.b    d1,(a0)+
  307. .Label5    dbra    d2,.Label1
  308.     rts
  309. .Potenzen    dc.l    1000000000
  310.     dc.l    100000000
  311.     dc.l    10000000
  312.     dc.l    1000000
  313.     dc.l    100000
  314.     dc.l    10000
  315.     dc.l    1000
  316.     dc.l    100
  317.     dc.l    10
  318.     dc.l    1
  319.  
  320.  
  321. .LineText    dc.b    10,$9b,$41," Line : "
  322. .Number    ds.b    12
  323.  
  324.  
  325. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  326. ; ­­                    GetLong                            ­­
  327. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  328. ; ­­ input   : a0    ^string                               ­­
  329. ; ­­                                                       ­­
  330. ; ­­ result :  a0    ^end of number+1                      ­­
  331. ; ­­           d0    number                                ­­
  332. ; ­­           d1     0  OK                                ­­
  333. ; ­­                  1  Overflow                          ­­
  334. ; ­­                 -1  error                             ­­
  335. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  336.  
  337. GetLong    movem.l    d3-d3/a1-a3,-(sp)
  338.     bsr.s    .Main
  339.     movem.l    (sp)+,d3-d3/a1-a3
  340.     rts
  341.  
  342. .Main    moveq.l    #0,d0        
  343.     moveq.l    #0,d1
  344.     moveq.l    #0,d2
  345. .Label1    move.b    (a0)+,d3        
  346.     cmp.b    #" ",d3
  347.     beq.s    .Label1
  348.     cmp.b    #9,d3
  349.     beq.s    .Label1
  350.  
  351.     cmp.b    #"$",d3        
  352.     beq    .Hex
  353.     cmp.b    #"%",d3        
  354.     beq    .Bin
  355.     cmp.b    #"@",d3        
  356.     beq    .Octal
  357.     cmp.b    #"-",d3        
  358.     beq.s    .Negativ
  359.     cmp.b    #"9",d3        
  360.     bhi    .Fehler
  361.     cmp.b    #"0"-1,d3
  362.     bhi    .Dezimal
  363.  
  364. .Fehler    subq.l    #1,a0        
  365.     moveq.l    #-1,d1        
  366.     rts
  367.  
  368. .Negativ    tst.b    d2        
  369.     bne.s    .Fehler
  370.     moveq.l    #1,d2        
  371.     bra    .Label1
  372.  
  373.  
  374.  
  375.  
  376. .Dezimal    subq.l    #1,a0        
  377.     move.l    a0,a1        
  378. .Label_D2    move.b    (a0)+,d3        
  379.     cmp.b    #"9",d3        
  380.     bhi.s    .Label_D3        
  381.     cmp.b    #"0"-1,d3
  382.     bhi.s    .Label_D2
  383.  
  384. .Label_D3    lea.l    .Data10(pc),a2        
  385.     subq.l    #1,a0        
  386.     move.l    a0,a3        
  387.  
  388. .Label_D5    move.l    (a2)+,d4        
  389.     beq.s    .Overflow        
  390.     moveq.l    #0,d3        
  391.     move.b    -(a3),d3        
  392.     sub.b    #"0"+1,d3        
  393.     bmi.s    .D_Zero        
  394. .Label_D4    add.l    d4,d0        
  395.     dbra    d3,.Label_D4
  396. .D_Zero    cmp.l    a3,a1        
  397.     bne.s    .Label_D5
  398.  
  399. .Vorzeichen    tst.b    d2        
  400.     beq.s    .NotNegative
  401.     tst.l    d0        
  402.     bmi    .Overflow
  403.     neg.l    d0        
  404. .NotNegative    moveq.l    #0,d1        
  405.     rts
  406.  
  407. .Data10    dc.l    1
  408.     dc.l    10
  409.     dc.l    100
  410.     dc.l    1000
  411.     dc.l    10000
  412.     dc.l    100000
  413.     dc.l    1000000
  414.     dc.l    10000000
  415.     dc.l    100000000
  416.     dc.l    1000000000
  417.     dc.l    0
  418.  
  419. .Overflow    moveq.l    #1,d1        
  420.     rts
  421.         
  422.  
  423.  
  424.  
  425. .Bin    move.b    (a0)+,d3        
  426.     cmp.b    #"0",d3
  427.     beq.s    .Label_B1
  428.     cmp.b    #"1",d3
  429.     bne    .Fehler
  430.     
  431. .Label_B1    lea.l    -1(a0),a1        
  432. .Label_B2    move.b    (a0)+,d3
  433.     cmp.b    #"1",d3        
  434.     beq.s    .Label_B2
  435.     cmp.b    #"0",d3
  436.     beq.s    .Label_B2
  437.     subq.l    #1,a0        
  438.     move.l    a0,a2        
  439.     moveq.l    #0,d1
  440. .Label_B3    move.b    -(a2),d3        
  441.     cmp.b    #"0",d3        
  442.     beq.s    .B_Zero
  443.     bset    d1,d0        
  444. .B_Zero    addq.l    #1,d1
  445.     cmp.b    #32,d1        
  446.     bhi.s    .Overflow        
  447.     cmp.l    a2,a1        
  448.     bne.s    .Label_B3
  449.     bra    .Vorzeichen
  450.  
  451.  
  452.  
  453.  
  454.  
  455. .Octal    move.b    (a0)+,d3        
  456.     cmp.b    #"7",d3
  457.     bhi    .Fehler
  458.     cmp.b    #"0"-1,d3
  459.     bls    .Fehler
  460.  
  461.     lea.l    -1(a0),a1        
  462. .Label_O2    move.b    (a0)+,d3        
  463.     cmp.b    #"7",d3        
  464.     bhi.s    .Label_O3        
  465.     cmp.b    #"0"-1,d3
  466.     bhi.s    .Label_O2
  467.  
  468. .Label_O3    lea.l    .Data8(pc),a2        
  469.     subq.l    #1,a0        
  470.     move.l    a0,a3        
  471.  
  472. .Label_O5    move.l    (a2)+,d4        
  473.     beq.s    .Overflow        
  474.     moveq.l    #0,d3        
  475.     move.b    -(a3),d3        
  476.     sub.b    #"0"+1,d3        
  477.     bmi.s    .O_Zero        
  478. .Label_O4    add.l    d4,d0        
  479.     dbra    d3,.Label_O4
  480. .O_Zero    cmp.l    a3,a1        
  481.     bne.s    .Label_O5
  482.  
  483.     bra    .Vorzeichen
  484.  
  485. .Data8    dc.l    @1
  486.     dc.l    @10
  487.     dc.l    @100
  488.     dc.l    @1000
  489.     dc.l    @10000
  490.     dc.l    @100000
  491.     dc.l    @1000000
  492.     dc.l    @10000000
  493.     dc.l    @100000000
  494.     dc.l    @1000000000
  495.     dc.l    @10000000000
  496.     dc.l    0
  497.  
  498.  
  499. .Hex    move.b    (a0)+,d3        
  500.     bsr.s    .Nibble
  501.     bmi    .Fehler        
  502.  
  503.  
  504.     lea.l    -1(a0),a1        
  505. .Label_H2    move.b    (a0)+,d3
  506.     bsr.s    .Nibble        
  507.     bpl.s    .Label_H2
  508.     subq.l    #1,a0        
  509.     move.l    a0,a2        
  510.     moveq.l    #0,d1
  511. .Label_H3    move.b    -(a2),d3        
  512.     bsr    .Nibble
  513.     lsl.l    d1,d4        
  514.     add.l    d4,d0        
  515.     addq.l    #4,d1
  516.     cmp.b    #32,d1        
  517.     bhi    .Overflow        
  518.     cmp.l    a2,a1        
  519.     bne.s    .Label_H3
  520.     bra    .Vorzeichen
  521.  
  522. .Nibble    moveq.l    #0,d4
  523.     cmp.b    #"a"-1,d3        
  524.     bls.s    .N1        
  525.     cmp.b    #"f",d3
  526.     bhi.s    .N_Error
  527.     sub.b    #"a"-"A",d3
  528. .N1    sub.b    #"0",d3
  529.     cmp.b    #9,d3        
  530.     bls.s    .Ziffer
  531.     sub.b    #"@"-"9",d3        
  532.     cmp.b    #$f,d3
  533.     bhi.s    .N_Error
  534. .Ziffer    move.b    d3,d4
  535.     rts
  536. .N_Error    moveq.l    #-1,d4        
  537.     rts
  538.     
  539.  
  540.  
  541. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  542. ; ­­                check whole command word              ­­
  543. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  544.  
  545. CheckWhole    move.l    (sp)+,a3        ; get return address
  546. .Label1    move.b    (a1)+,d1
  547.     beq.s    .Exit
  548.     move.b    (a0)+,d0        ; next character
  549.     beq    SytaxError
  550.     bsr    UpCase
  551.     cmp.b    d1,d0        ; compare characters
  552.     bne    SytaxError
  553.     bra.s    .Label1
  554. .Exit    jmp    (a3)        ; return
  555.     
  556.  
  557. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  558. ; ­­                     UpCase d0                        ­­
  559. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  560.  
  561. UpCase    cmp.b    #"a"-1,d0        ; range "a"-"z"
  562.     bls.s    .Exit
  563.     cmp.b    #"z",d0
  564.     bhi.s    .Exit
  565.     sub.b    #"a"-"A",d0
  566. .Exit    rts
  567.  
  568. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  569. ; ­­              Read line from Source                   ­­
  570. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  571.  
  572. ReadLine    moveq.l    #(512/4)-1,d0        ; clear buffer
  573.     lea.l    Line(pc),a0
  574. .Label1    clr.l    (a0)+
  575.     dbra    d0,.Label1
  576.  
  577.  
  578.     move.l    #Line,d2
  579. .Loop    move.l    Source_FH(pc),d1    ; read one byte
  580.     moveq.l    #1,d3
  581.     DOS    Read
  582.     tst.l    d0
  583.     beq.s    .EndOfFile
  584.     cmp.l    d3,d0
  585.     bne.s    .ReadError
  586.     move.l    d2,a0
  587.     cmp.l    #Line,a0        ; first byte ?
  588.     bne.s    .Label2
  589.     cmp.b    #" ",(a0)        ; skip spaces & tabs in front of command
  590.     beq.s    .Loop
  591.     cmp.b    #9,(a0)
  592.     beq.s    .Loop
  593. .Label2    cmp.b    #10,(a0)        ; end of line ?
  594.     beq.s    .Ok
  595.     addq.l    #1,d2
  596.     cmp.l    #Line+512,d2        ; end of buffer ?
  597.     bne.s    .Loop
  598.     moveq.l    #1,d0        ; line too long !!!
  599.     rts
  600. .EndOfFile    
  601. .Ok    moveq.l    #0,d0        ; no error 
  602.     rts
  603. .ReadError    moveq.l    #-1,d0        ; dos error
  604.     rts
  605.  
  606. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  607. ; ­­    get pointer to next command (skip spaces ...)     ­­
  608. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  609.  
  610. ; return d0     0 empty line
  611. ;               1 command line
  612. ;        a0  :   ^command
  613.  
  614. NextCommand    move.b    (a0)+,d0
  615.     beq.s    .EndOfLine
  616.     cmp.b    #10,d0        ; LF ?
  617.     beq.s    .EndOfLine
  618.  
  619.     cmp.b    #" ",d0        ; space ?
  620.     beq.s    NextCommand
  621.     cmp.b    #9,d0        ; tab ?
  622.     beq.s    NextCommand
  623.     cmp.b    #"*",d0        ; rem line ?
  624.     beq.s    .EndOfLine
  625.     cmp.b    #";",d0        ; rem line ?
  626.     beq.s    .EndOfLine
  627.     subq.l    #1,a0        ; ^command
  628.     moveq.l    #1,d0
  629.     rts
  630. .EndOfLine    moveq.l    #0,d0
  631.     rts
  632.  
  633. Line    ds.b    512
  634.  
  635.  
  636. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  637. ; ­­                     BEGIN                            ­­
  638. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  639.  
  640. BEGIN    clr.b    LastIF        ; last command wasn't IF
  641.     lea.l    .BeginText(pc),a1    ; check rest of command
  642.     bsr    CheckWhole
  643.     bsr    NextCommand        ; no more chars in that line ?
  644.     tst    d0
  645.     bne    SytaxError        ; this command needs no arguments !
  646.  
  647.     addq.l    #1,BEGINCounter
  648.     move.l    Object_FH(pc),d1    ; write to output
  649.     move.l    #.BeginCode,d2
  650.     moveq.l    #2,d3
  651.     DOS    Write
  652.     cmp.l    d0,d3        ; error ?
  653.     beq    NextLine
  654.     bra    DOSError
  655. .BeginText    dc.b    "EGIN",0
  656.     even
  657. .BeginCode    dc.b    "B",0
  658.     even
  659.  
  660. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  661. ; ­­                       END                            ­­
  662. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  663.  
  664. END    clr.b    LastIF        ; last command wasn't IF
  665.     lea.l    .EndText(pc),a1    ; check rest of command
  666.     bsr    CheckWhole
  667.     bsr    NextCommand        ; no more chars in that line ?
  668.     tst    d0
  669.     bne    SytaxError        ; this command needs no arguments !
  670.     subq.l    #1,BEGINCounter
  671.     bmi    .Error2
  672.     move.l    Object_FH(pc),d1    ; write to output
  673.     move.l    #.EndCode,d2
  674.     moveq.l    #2,d3
  675.     DOS    Write
  676.     cmp.l    d0,d3        ; error ?
  677.     beq    NextLine
  678.     bra    DOSError
  679. .Error2    PSC_ERROR    <"END without BEGIN !">
  680.     bra    DeleteObject
  681. .EndText    dc.b    "ND",0
  682.     even
  683. .EndCode    dc.b    "E",0
  684.     even
  685. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  686. ; ­­                       QUIT                           ­­
  687. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  688.  
  689. QUIT    clr.b    LastIF        ; last command wasn't IF
  690.     lea.l    .QuitText(pc),a1    ; check rest of command
  691.     bsr    CheckWhole
  692.     bsr    NextCommand        ; no more chars in that line ?
  693.     tst    d0
  694.     bne    SytaxError        ; this command needs no arguments !
  695.     move.l    Object_FH(pc),d1    ; write to output
  696.     move.l    #.QuitCode,d2
  697.     moveq.l    #2,d3
  698.     DOS    Write
  699.     cmp.l    d0,d3        ; error ?
  700.     beq    NextLine
  701.     bra    DOSError
  702. .QuitText    dc.b    "UIT",0
  703.     even
  704. .QuitCode    dc.b    "Q",0
  705.     even
  706.  
  707. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  708. ; ­­                       TEXT                           ­­
  709. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  710.  
  711. TEXT    clr.b    LastIF        ; last command wasn't IF
  712.     lea.l    .TextText(pc),a1    ; check rest of command
  713.     bsr    CheckWhole
  714.     bsr    NextCommand        ; get ^string
  715.     lea.l    .Buffer(pc),a1
  716.     tst    d0
  717.     beq.s    .Label3        ; just LF    
  718. .Label1    move.b    (a0)+,d0
  719.     cmp.b    #"'",d0        ; " or ' ?
  720.     beq.s    .Label2
  721.     cmp.b    #'"',d0
  722.     bne    SytaxError        ; else sytax error 
  723. .Label2    move.b    (a0)+,d1        ; copy string to buffer
  724.     beq.s    .Label3
  725.     cmp.b    #10,d1        ; end of string : 0-byte, LF, "' ?
  726.     beq.s    .Label3
  727.     cmp.b    d0,d1    
  728.     beq.s    .Label3
  729.     move.b    d1,(a1)+
  730.     bra.s    .Label2
  731. .Label3    move.b    #10,(a1)+
  732.     lea.l    .Buffer(pc),a2
  733.     sub.l    a2,a1
  734.     move.l    a1,d3
  735.     move.b    d3,.Size        ; write size
  736.     addq.l    #2+1,d3        ; add Command and
  737.     bclr    #0,d3        ; get word size
  738.  
  739.     move.l    Object_FH(pc),d1    ; write to output
  740.     move.l    #.TextCode,d2
  741.     move.l    a0,a2        ; save a0
  742.     DOS    Write
  743.     cmp.l    d0,d3        ; error ?
  744.     bne    DOSError
  745.     move.l    a2,a0
  746.     bsr    NextCommand
  747.     tst    d0
  748.     bne    SytaxError        ; end of line ?
  749.     bra    NextLine        
  750.     
  751. .TextText    dc.b    "EXT",0
  752.     even
  753. .TextCode    dc.b    "T"
  754. .Size    dc.b    0
  755. .Buffer    ds.b    256
  756.     even
  757. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  758. ; ­­                         IF                           ­­
  759. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  760.  
  761. _IF    move.b    #1,LastIF        ; last command was IF
  762.     lea.l    .IFText(pc),a1        ; check rest of command
  763.     bsr    CheckWhole
  764.     bsr    NextCommand        ; get argument
  765.     beq    .Error        ; no argument ...    
  766.     move.b    (a0)+,d0
  767.     bsr    UpCase
  768.     cmp.b    #"T",d0
  769.     beq.s    .True
  770.     cmp.b    #"F",d0
  771.     bne.s    .Error
  772.     lea.l    .FalseText(pc),a1    ; check rest of boolean expression
  773.     bsr    CheckWhole
  774.     move.b    #1,.Boolean        ; boolean = FALSE
  775. .Write    move.l    Object_FH(pc),d1    ; write to output
  776.     move.l    #.IFCode,d2
  777.     moveq.l    #2,d3
  778.     DOS    Write
  779.     cmp.l    d0,d3        ; error ?
  780.     beq    NextLine
  781.     bra    DOSError
  782. .True    lea.l    .TrueText(pc),a1    ; check rest of boolean expression
  783.     bsr    CheckWhole
  784.     clr.b    .Boolean        ; boolean = TRUE
  785.     bra.s    .Write
  786. .Error    PSC_ERROR    <"IF without boolean expression (TRUE/FALSE) !">
  787.     bra    DeleteObject
  788.  
  789. .IFText    dc.b    "F",0
  790.     even
  791. .FalseText    dc.b    "ALSE",0
  792.     even
  793. .TrueText    dc.b    "RUE",0
  794.     even
  795. .IFCode    dc.b    "I"
  796. .Boolean    dc.b    0
  797.     even
  798.  
  799. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  800. ; ­­                   CHECK / PATCH                      ­­
  801. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  802.  
  803. CHECK    moveq    #"C",d0        ; Check mode
  804.     lea.l    .CheckText(pc),a1    ; check rest of command
  805.     bra.s    Patch_Check
  806. .CheckText    dc.b    "HECK",0
  807.     even
  808. PATCH_2    moveq.b    #"p",d0        ; patch mode
  809.     bra.s    Patch_Check        ; (patch command without "PATCH")
  810.  
  811.  
  812. PATCH    move.b    #"P",d0        ; patch mode
  813.     lea.l    .PatchText(pc),a1    ; check rest of command
  814.     bra.s    Patch_Check
  815. .PatchText    dc.b    "ATCH",0
  816.     even    
  817.  
  818. ; both command have nearly the same sytax !
  819.  
  820. Patch_Check    cmp.b    #"p",d0
  821.     bne.s    .Label0
  822.     move.b    #"P",.Code
  823.     bra.s    .Label_1
  824. .Label0    move.b    d0,.Code
  825.  
  826. .Label_1    bsr    CheckWhole
  827.     clr.b    LastIF        ; last command wasn't IF
  828.     bsr    GetLong        ; get file offset
  829.     tst.l    d1
  830.     bne    SytaxError        ; wrong file offset !
  831.     move.l    d0,.Offset
  832. .Label1    move.b    (a0)+,d0
  833.     cmp.b    #" ",d0        ; skip spaces, tabs ,"=" & ":"
  834.     beq.s    .Label1
  835.     cmp.b    #9,d0
  836.     beq.s    .Label1
  837.     cmp.b    #":",d0
  838.     beq.s    .Label1
  839.     cmp.b    #"=",d0
  840.     beq.s    .Label1
  841.  
  842.     cmp.b    #"'",d0
  843.     beq    .String        ; string !
  844.     cmp.b    #'"',d0
  845.     beq    .String        ; string !
  846.  
  847.     clr.b    .Size
  848.     subq.l    #1,a0
  849.     lea.l    .Args(pc),a1
  850. .Label10    bsr    NextCommand        ; more chars in that line ?
  851.     tst    d0
  852.     beq    .Label2        ; NO !
  853.     cmp.b    #"$",(a0)
  854.     bne.s    .Label11
  855.     addq.l    #1,a0        ; skip "$"
  856. .Label11    bsr    GetHex        ; read byte
  857.     tst.l    d0        ; error ?
  858.     bmi    SytaxError
  859.     move.b    d0,(a1)+
  860.     addq.b    #1,.Size
  861.     cmp.b    #255,.Size        ; at least 255 bytes
  862.     bne.s    .Label10
  863.     bra    .Label5
  864.  
  865. .String    lea.l    .Args(pc),a1
  866.     moveq.l    #0,d2
  867. .Label3    move.b    (a0)+,d1        ; next character
  868.     beq.s    .Label2        ; end of file ?
  869.     cmp.b    #10,d1        ; end of line ?
  870.     beq.s    .Label4
  871.     cmp.b    d0,d1        ; end of string ?
  872.     beq.s    .Label4
  873.     move.b    d1,(a1)+        ; write to buffer 
  874.     addq.l    #1,d2
  875.     cmp.w    #255,d2        ; at least 255 bytes !
  876.     bls.s    .Label3
  877. .Label5    PSC_ERROR    <"Line too long !">
  878.     bra    DeleteObject
  879.  
  880.  
  881. .Label4    move.b    d2,.Size
  882.  
  883. .Label2    tst.b    .Size
  884.     beq    SytaxError
  885.     bsr    NextCommand        ; no more chars in that line ?
  886.     tst    d0
  887.     bne    SytaxError        ; this command needs no arguments !
  888.     move.l    Object_FH(pc),d1    ; write to output
  889.     move.l    #.Code,d2
  890.     move.b    .Size(pc),d3
  891.     addq.l    #2+4+1,d3
  892.     bclr    #0,d3        ; even !
  893.     DOS    Write
  894.     cmp.l    d0,d3        ; error ?
  895.     beq    NextLine
  896.     bra    DOSError
  897.     even
  898. .Code    dc.b    "C"
  899. .Size    dc.b    0
  900. .Offset    dc.l    0
  901. .Args    ds.b    256
  902.     even
  903.  
  904.  
  905. GetHex    move.b    (a0)+,d0
  906.     lea.l    .Hex(pc),a2        ; ASCII -> Hex
  907.     moveq.l    #-1,d1        ; get 1. nibble
  908. .W3    addq.l    #1,d1
  909.     cmp.w    #32,d1
  910.     bhi.s    .W6
  911.     cmp.b    (a2)+,d0
  912.     bne.s    .W3
  913.     and.w    #$f,d1
  914.     move.b    (a0)+,d0
  915.     lea.l    .Hex(pc),a2        ; ASCII -> Hex
  916.     moveq.l    #-1,d2        ; get 2. nibble
  917. .W4    addq.l    #1,d2
  918.     cmp.w    #32,d2
  919.     bhi.s    .W6
  920.     cmp.b    (a2)+,d0
  921.     bne.s    .W4
  922.     and.w    #$f,d2
  923.     lsl.b    #4,d1
  924.     or.b    d1,d2
  925. .W5    move.b    d2,d0
  926.     rts
  927. .W6    moveq.l    #-1,d0
  928.     rts
  929. .Hex    dc.b    "0123456789abcdef"
  930.     dc.b    "0123456789ABCDEF"
  931.  
  932.  
  933.  
  934.  
  935. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  936. ; ­­                       COMMAND                            ­­
  937. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  938. ; ­­                    prepare  Args                         ­­
  939. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  940.  
  941.  
  942. COMMAND    move.l    CommandString(pc),a0
  943.     move.l    a0,a1
  944.     moveq.l    #0,d0
  945.     bsr.s    .Label1
  946.     cmp.b    #3,d0        ; number of args ?
  947.     beq.s    .Label10
  948.     moveq.l    #-1,d0
  949.     rts
  950. .Label10    move.l    CommandString(pc),a0
  951.     move.l    a0,InfoName
  952. .Label11    tst.b    (a0)+
  953.     bne.s    .Label11
  954.     move.l    a0,SourceName
  955. .Label12    tst.b    (a0)+
  956.     bne.s    .Label12
  957.     move.l    a0,PatchName
  958.     moveq.l    #0,d0
  959.     rts    
  960.  
  961. .Label1    bsr.s    .Next        ; prepare command line
  962.     tst.b    d1
  963.     beq.s    .End
  964.     addq.l    #1,d0
  965.     cmp.b    #"'",d1
  966.     beq.s    .Quote    
  967.     cmp.b    #'"',d1
  968.     beq.s    .Quote    
  969.     subq.l    #1,a0
  970.  
  971. .Label2    move.b    (a0)+,d1
  972.     beq.s    .LastArg
  973.     cmp.b    #" ",d1    
  974.     beq.s    .EndOfArg
  975.     cmp.b    #9,d1
  976.     beq.s    .EndOfArg
  977.     move.b    d1,(a1)+    
  978.     bra.s    .Label2
  979.  
  980. .EndOfArg    clr.b    (a1)+    
  981.     bra.s    .Label1    
  982.  
  983. .Quote    move.b    (a0)+,d2    
  984.     beq.s    .LastArg
  985.     cmp.b    d2,d1    
  986.     beq.s    .EndOfArg
  987.     move.b    d2,(a1)+    
  988.     bra.s    .Quote
  989.  
  990. .LastArg    clr.b    (a1)+
  991. .End    rts
  992.  
  993. .Next    move.b    (a0)+,d1
  994.     cmp.b    #" ",d1
  995.     beq.s    .Next
  996.     cmp.b    #9,d1
  997.     beq.s    .Next
  998.     rts
  999.  
  1000.  
  1001. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  1002. ; ­­                    Write Patch INFO string               ­­
  1003. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  1004.  
  1005.  
  1006. WRITE_INFO    move.l    InfoName(pc),d1    ; open info file
  1007.     move.l    #MODE_OLDFILE,d2
  1008.     DOS    Open
  1009.     move.l    d0,Info_FH
  1010.     bne.s    .Label1
  1011.     PSC_ERROR    <"couldn't open info file !",10>
  1012.     bra    .NoInfo
  1013.  
  1014. .Label1    moveq.l    #0,d4        ; file size
  1015.  
  1016. .Label2    moveq.l    #0,d0        ; check if CTRL-C 
  1017.     moveq.l    #0,d1
  1018.     CALLEXEC    SetSignal
  1019.     btst    #12,d0
  1020.     beq.s    .NoUserBreak
  1021.     DOS_TEXT    <" User break .",10>    ; write msg
  1022.     bra    .Error
  1023.  
  1024. .NoUserBreak    move.l    Info_FH(pc),d1        ; copy info string 
  1025.     move.l    #.Buffer,d2
  1026.     move.l    #256,d3
  1027.     DOS    Read        ; read part of info string
  1028.     move.l    d0,d3
  1029.     bmi.s    .DosError        ; DOS error ?
  1030.     beq.s    .End        ; end of info string ?
  1031.     add.l    d0,d4        ; calculate file size
  1032.     
  1033.     move.l    #.Buffer,d2
  1034.     move.l    Object_FH(pc),d1
  1035.     DOS    Write        ; copy to patch file        
  1036.     cmp.l    d0,d3
  1037.     beq    .Label2        ; dos error ?
  1038.  
  1039. .DosError    PSC_ERROR    <"DOS error !">
  1040. .Error    move.l    Info_FH(pc),d1
  1041.     DOS    Close
  1042. .NoInfo    moveq.l    #-1,d0        ; error
  1043.     rts
  1044.  
  1045.  
  1046. .End    moveq.l    #1,d3        ; terminate info string with $00 byte and write word alligned
  1047.     btst    #0,d4
  1048.     bne.s    .Alligned        ; alligned afteradding $00 byte ?
  1049.     addq.l    #1,d3
  1050. .Alligned    move.l    #.Buffer2,d2
  1051.     move.l    Object_FH(pc),d1
  1052.     DOS    Write
  1053.     cmp.l    d0,d3
  1054.     bne.s    .DosError
  1055.  
  1056. .OK    move.l    Info_FH(pc),d1        ; close file
  1057.     DOS    Close
  1058.     moveq.l    #0,d0        ; no error
  1059.     rts
  1060.  
  1061. .Buffer    ds.b    256+2
  1062.     even
  1063. .Buffer2    dc.b    0,0
  1064.  
  1065.  
  1066. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  1067. ; ­­                    Write Patch Module                    ­­
  1068. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  1069.  
  1070.  
  1071. WRITE_MODULE    move.l    #EXEC_HEADER,d2    ; write Executable Header
  1072.     move.l    #EXEC_HEADER_SIZE,d3
  1073.     move.l    Object_FH(pc),d1
  1074.     DOS    Write
  1075.     cmp.l    d0,d3
  1076.     bne.s    .DosError
  1077.     move.l    #PATCH_MODULE_START,d2
  1078.     move.l    #PATCH_MODULE_SIZE,d3
  1079.     move.l    Object_FH(pc),d1
  1080.     DOS    Write        ; copy to patch module
  1081.     cmp.l    d0,d3
  1082.     beq    .Label2        ; dos error ?
  1083. .DosError    PSC_ERROR    <"DOS error !">
  1084.     moveq.l    #-1,d0
  1085.     rts
  1086. .Label2    moveq.l    #0,d0        ; check if CTRL-C 
  1087.     moveq.l    #0,d1
  1088.     CALLEXEC    SetSignal
  1089.     btst    #12,d0
  1090.     beq.s    .NoUserBreak
  1091.     DOS_TEXT    <" User break .",10>    ; write msg
  1092.     moveq.l    #-1,d0
  1093.     rts
  1094. .NoUserBreak    moveq.l    #0,d0
  1095.     rts
  1096.  
  1097.  
  1098. EXEC_HEADER    dc.l    $3f3
  1099.     dc.l    0
  1100.     dc.l    1
  1101.     dc.l    0
  1102.     dc.l    0
  1103. HUNK_SIZE1    dc.l    -1
  1104.     dc.l    $3e9
  1105. HUNK_SIZE2    dc.l    -1
  1106. EXEC_HEADER_END
  1107. EXEC_HEADER_SIZE  equ EXEC_HEADER_END-EXEC_HEADER
  1108.  
  1109.  
  1110. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  1111. ; ­­                    saving as executable                  ­­
  1112. ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  1113.  
  1114. EXECUTABLE    move.l    Object_FH(pc),d1
  1115.     moveq.l    #0,d2
  1116.     moveq.l    #OFFSET_CURRENT,d3
  1117.     DOS    Seek        ; get file pos
  1118.     sub.l    #EXEC_HEADER_SIZE-4,d0
  1119.     move.l    d0,d1
  1120.     lsr.l    #2,d1
  1121.     move.l    d1,HUNK_SIZE1
  1122.     move.l    d1,HUNK_SIZE2
  1123.     and.l    #%11,d0
  1124.     moveq.l    #4,d1
  1125.     sub.w    d0,d1
  1126.     and.w    #%11,d1        ; bytes to add to get longword alligned
  1127.     move.l    #.Data+4,d2
  1128.     moveq.l    #4,d3
  1129.     add.l    d1,d3
  1130.     sub.l    d1,d2
  1131.     move.l    Object_FH(pc),d1
  1132.     DOS    Write        ; write pad bytes and $3f2
  1133.     cmp.l    d0,d3
  1134.     beq.s    .Label1
  1135. .Error    PSC_ERROR    <"DOS error !">
  1136.     moveq.l    #-1,d0
  1137.     rts
  1138. .Label1    moveq.l    #0,d0        ; check if CTRL-C 
  1139.     moveq.l    #0,d1
  1140.     CALLEXEC    SetSignal
  1141.     btst    #12,d0
  1142.     beq.s    .NoUserBreak
  1143.     DOS_TEXT    <" User break .",10>    ; write msg
  1144.     moveq.l    #-1,d0
  1145.     rts
  1146. .NoUserBreak    move.l    Object_FH(pc),d1    ; write hunk size
  1147.     moveq.l    #0,d2
  1148.     moveq.l    #OFFSET_BEGINNING,d3
  1149.     DOS    Seek        ; get file pos
  1150.     move.l    #EXEC_HEADER,d2    ; write Executable Header (second time)
  1151.     move.l    #EXEC_HEADER_SIZE,d3
  1152.     move.l    Object_FH(pc),d1
  1153.     DOS    Write
  1154.     cmp.l    d0,d3
  1155.     bne    .Error
  1156.     moveq.l    #0,d0
  1157.     rts
  1158.     
  1159. .Data    dc.l    0
  1160.     dc.l    $3f2
  1161.